package com.digitaldreamers.spaceshooter.gameobject;

import org.andengine.entity.Entity;
import org.andengine.entity.IEntity;
import org.andengine.entity.modifier.IEntityModifier;
import org.andengine.entity.modifier.IEntityModifier.IEntityModifierListener;
import org.andengine.entity.modifier.LoopEntityModifier;
import org.andengine.entity.modifier.MoveModifier;
import org.andengine.entity.modifier.ParallelEntityModifier;
import org.andengine.entity.modifier.SequenceEntityModifier;
import org.andengine.entity.sprite.AnimatedSprite;
import org.andengine.entity.sprite.Sprite;
import org.andengine.input.sensor.acceleration.AccelerationData;
import org.andengine.input.sensor.acceleration.IAccelerationListener;
import org.andengine.util.modifier.IModifier;

import com.digitaldreamers.spaceshooter.Constants;
import com.digitaldreamers.spaceshooter.effect.entitymodifier.MyAlphaModifier;
import com.digitaldreamers.spaceshooter.scene.GameScene;

public class PlayerShip extends Entity implements IAccelerationListener {
	private boolean mInitialBorn;
	private boolean mInitialMoving;
	
	public float mSpeed = 1f;
	
	private long mlastPositionUpdateTime;
	private long[] mDurations;
	private int[] mLeftFrames;
	private int[] mMiddleFrames;
	private int[] mRightFrames;
	
	private GameScene mGameScene;
	private AnimatedSprite mPlayerSpaceShipSprite;
	private IEntityModifier mInitEntityModifier;
	
	public PlayerShip(GameScene gameScene, AnimatedSprite playerSpaceShipSprite) {
		this.mInitialBorn = true;
		this.mInitialMoving = true;
		this.mlastPositionUpdateTime = 0;
		
		this.mDurations = new long[3];
		this.mDurations[0] = Constants.USER_SPACESHIP_UPDATE_MILLISECONDS;
		this.mDurations[1] = Constants.USER_SPACESHIP_UPDATE_MILLISECONDS;
		this.mDurations[2] = Constants.USER_SPACESHIP_UPDATE_MILLISECONDS;
		
		this.mLeftFrames = new int[3];
		this.mLeftFrames[0] = 0;
		this.mLeftFrames[1] = 3;
		this.mLeftFrames[2] = 6;
		
		this.mMiddleFrames = new int[3];
		this.mMiddleFrames[0] = 1;
		this.mMiddleFrames[1] = 4;
		this.mMiddleFrames[2] = 7;
		
		this.mRightFrames = new int[3];
		this.mRightFrames[0] = 2;
		this.mRightFrames[1] = 5;
		this.mRightFrames[2] = 8;
		
		this.mGameScene = gameScene;
		this.mPlayerSpaceShipSprite = playerSpaceShipSprite;
		this.setSize(this.mPlayerSpaceShipSprite.getWidth(), this.mPlayerSpaceShipSprite.getHeight());
		this.mPlayerSpaceShipSprite.setPosition(this.getWidth() / 2f, this.getHeight() / 2f);
		this.attachChild(this.mPlayerSpaceShipSprite);
		
		/*Line line1 = new Line(0, 0, 0, this.getHeight(), this.mGameScene.mVBOM);
		line1.setColor(0, 1, 0);
		Line line2 = new Line(0, 0, this.getWidth(), 0, this.mGameScene.mVBOM);
		line2.setColor(0, 1, 0);
		Line line3 = new Line(0, this.getHeight(), this.getWidth(), this.getHeight(), this.mGameScene.mVBOM);
		line3.setColor(0, 1, 0);
		Line line4 = new Line(this.getWidth(), this.getHeight(), this.getWidth(), 0, this.mGameScene.mVBOM);
		line4.setColor(0, 1, 0);
		Line line5 = new Line(this.getWidth() /2f, this.getHeight(), this.getWidth() /2f, 0, this.mGameScene.mVBOM);
		line5.setColor(0, 1, 0);
		this.attachChild(line1);
		this.attachChild(line2);
		this.attachChild(line3);
		this.attachChild(line4);
		this.attachChild(line5);*/
		
		this.createInitEntityModifier();
	}
	
	public void initialize() {
		this.mPlayerSpaceShipSprite.animate(this.mDurations, this.mMiddleFrames, true);
		this.registerEntityModifier(this.mInitEntityModifier);
	}
	
	public void fireLaserBeam() {
		LaserBeam laserBeam = this.createLaserBeam();
		laserBeam.setPosition(this.getWidth() / 2f, this.getHeight() + Constants.BULLET_OFFSET);
		this.attachChild(laserBeam);
	}
	
	@Override
	public void onAccelerationChanged(AccelerationData accelerationData) {
		long currentTime = System.currentTimeMillis();
		if(currentTime - this.mlastPositionUpdateTime > Constants.USER_SPACESHIP_UPDATE_MILLISECONDS) {
			if(!this.mInitialMoving ) {
				this.updatePosition(accelerationData);
			}
			this.mlastPositionUpdateTime = currentTime;
		}
	}
	
	@Override
	public void onAccelerationAccuracyChanged(AccelerationData pAccelerationData) {
		
	}
	
	private void createInitEntityModifier() {
		@SuppressWarnings("deprecation")
		MoveModifier moveModifier = new MoveModifier(Constants.USER_SPACESHIP_INIT_MOVING_SECONDS, this.mGameScene.mCameraMiddleX, -this.mPlayerSpaceShipSprite.getHeightScaled(), this.mGameScene.mCameraMiddleX, this.mPlayerSpaceShipSprite.getHeightScaled());
		MyAlphaModifier hideAlphaModifier = new MyAlphaModifier(Constants.USER_SPACESHIP_INIT_SHOW_HIDE_SECONDS, 1f, 0f);
		MyAlphaModifier showAlphaModifier = new MyAlphaModifier(Constants.USER_SPACESHIP_INIT_SHOW_HIDE_SECONDS, 0f, 1f);
		SequenceEntityModifier showHideEntityModifier = new SequenceEntityModifier(hideAlphaModifier, showAlphaModifier);
		LoopEntityModifier loopShowHideEntityModifier = new LoopEntityModifier(showHideEntityModifier, Constants.USER_SPACESHIP_INIT_TWINKLE_TIMES);
		ParallelEntityModifier parallelEntityModifier = new ParallelEntityModifier(moveModifier, loopShowHideEntityModifier);
		
		IEntityModifierListener initMovingModifierListener = new IEntityModifierListener() {
			@Override
			public void onModifierStarted(IModifier<IEntity> pModifier, IEntity pItem) {
				PlayerShip.this.mInitialMoving = true;
			}
			
			@Override
			public void onModifierFinished(IModifier<IEntity> pModifier, IEntity pItem) {
				PlayerShip.this.mInitialMoving = false;
			}
		};
		moveModifier.addModifierListener(initMovingModifierListener);
		
		IEntityModifierListener initBornModifierListener = new IEntityModifierListener() {
			@Override
			public void onModifierStarted(IModifier<IEntity> pModifier, IEntity pItem) {
				PlayerShip.this.mInitialBorn = true;
			}
			
			@Override
			public void onModifierFinished(IModifier<IEntity> pModifier, IEntity pItem) {
				PlayerShip.this.mInitialBorn = false;
			}
		};
		parallelEntityModifier.addModifierListener(initBornModifierListener);
		
		this.mInitEntityModifier = parallelEntityModifier;
	}
	
	private LaserBeam createLaserBeam() {
		Sprite laserBeamSprite = new Sprite(-1000, -1000, this.mGameScene.mResourceManager.mLaserBeamTextureRegion, this.mGameScene.mVBOM);
		LaserBeam laserBeam = new LaserBeam(this.mGameScene, this.mGameScene.mResourceManager.mParticlePointTextureRegion, laserBeamSprite);
		return laserBeam;
	}
	
	private void updatePosition(AccelerationData accelerationData) {
		float x = accelerationData.getX();
		float y = accelerationData.getY();
		this.changeAnimationSprites(x);
		this.move(x, y);
	}
	
	private void changeAnimationSprites(float x) {
		if(x <= Constants.USER_SPACESHIP_FLY_LEFT) {
			this.mPlayerSpaceShipSprite.animate(this.mDurations, this.mLeftFrames, true);
		} else if(x >= Constants.USER_SPACESHIP_FLY_RIGHT) {
			this.mPlayerSpaceShipSprite.animate(this.mDurations, this.mRightFrames, true);
		} else {
			this.mPlayerSpaceShipSprite.animate(this.mDurations, this.mMiddleFrames, true);
		}
	}
	
	@SuppressWarnings("deprecation")
	private void move(float x, float y) {
		float currentX = this.getX();
		float newX = currentX + x;
		float halfWidth = this.getWidthScaled() / 2f;
		float newLeft = newX - halfWidth;
		float newRight = newX + halfWidth;
		
		if(newLeft >= 0 && newRight <= this.mGameScene.mCameraWidth) {
			this.setX(newX);
		}
	}
}
